#ifndef _D3D_D3DLightShader_
#define _D3D_D3DLightShader_

#include <windows.h>
#include <d3dx9.h>

#include "..\..\common\types.h"
#include "..\..\common\arraylist.hpp"

#include "..\interface_types.h"
#include "..\d3d.h"
#include "..\d3d_util.h"
#include "d3d_shader.h"

#include "..\..\common\string.h"

/**************************************
 *
 **************************************/
struct D3DLightShader : public D3DShader
{
private:
	friend class CD3D9Device; 
	friend struct D3DWaterShader; 
	friend struct D3DReflectShader; 
	D3DLightShader(CD3D9Device *pDevice); 
	RenderTarget* m_RTDepth; 
	RenderTarget* m_RTStaticLighting; 
	RenderTarget* m_RTNormal;
	RenderTarget* m_RTVelocity; 
	RenderTarget* m_RTLightbuffer; 
	
	LPDIRECT3DTEXTURE9 pLightTextureA; 
	//SunData m_skyData;
	D3DLight::ShaderData m_skyData;
	bool m_skyActive;
	
	//unsigned int m_QualityDenominator;
	LPD3DXMESH m_pLightSphere;
	LPD3DXMESH m_pLightCylinder;

	HashTable<InstanceData, D3DRenderable*> m_MaskMeshHashInstances; 
	LPDIRECT3DVERTEXBUFFER9 mp_MaskInstanceVB; 
	unsigned int	mui_LastMaskInstanceCount; 

	D3DXMATRIX matViewProjection; 
	D3DXMATRIX matInvViewProjection; 
	D3DXMATRIX matLastView;
	bool mb_Locked; 
	//bool mb_SwapTarget;
	
	HRESULT ConstructSubGroupInstanceBuffer(HashTable<InstanceData, D3DRenderable*>* pSubGroup, unsigned int* pLastInstanceCount, LPDIRECT3DVERTEXBUFFER9* pInstanceBuffer);
	HRESULT ConstructInstanceBuffer();
	
	D3DXHANDLE mp_LastViewHandle;
	D3DXHANDLE mp_DepthNormalHandle; 
	D3DXHANDLE mp_MaskDepthNormalHandle; 
	D3DXHANDLE mp_ComputeLightingHandle; 
	D3DXHANDLE mp_ComputeDirLightingHandle; 
	D3DXHANDLE mp_ComputeSunLightingHandle; 
	D3DXHANDLE mp_InvViewProjHandle; 
	D3DXHANDLE mp_CameraWSHandle; 
	D3DXHANDLE m_pInvMapDimensions; 
	D3DXHANDLE mp_LightDataHandle; 
	
	void RenderNormalDepthBuffer(); 
	void RenderLighting(); 
	void RenderOminLighting();
	void RenderDirectionalLighting();
	void RenderSunLighting();
	void ReleaseResources(); 
	void CreateRenderTargets();
	void ReleaseRT(RenderTarget** pRT); 

	HRESULT InitalizeParameters(LPD3DXEFFECT pEffect);
public:
	static string Identifier(); 
	HRESULT Release(); 
	HRESULT Create(const string& szFilename); 
	
	void PostExecute(); 
	HRESULT	Reload(void); 
	void AddRenderQue(D3DRenderable* pMesh, const Matrix4f& transform); 
	void Execute(const int flags = RENDER_DEFAULT); 
	string GetType() const; 
	void PreExecute();

	void SetSkyData(const SunData &skyData);
	LPDIRECT3DTEXTURE9 GetLightBuffer();
	LPDIRECT3DTEXTURE9 GetVelocityBuffer();
}; 


#endif